﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Matrix.MaKaYunShang.Model.Dto;
using Microsoft.AspNet.SignalR;

namespace Matrix.MaKaYunShang.BLL.Hubs
{
    public class NotificationHub : Hub, INotifiicationHubServer, INotificationHubClient
    {
        private static readonly Lazy<NotificationHub> LazyNotificationHub;
        private static readonly List<McConnectedClientInfo> ConnectedUsers = new List<McConnectedClientInfo>();

        public static NotificationHub Instance
        {
            get { return LazyNotificationHub.Value; }
        }

        public static INotifiicationHubServer Server
        {
            get { return Instance; }
        }

        public static INotificationHubClient Client
        {
            get { return Instance; }
        }

        static NotificationHub()
        {
            LazyNotificationHub =
                new Lazy<NotificationHub>(
                    () =>
                        new NotificationHub
                        {
                            GlobalContext = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>()
                        });
        }

        /// <summary>
        /// 离线
        /// </summary>
        public override Task OnDisconnected(bool stopCalled)
        {
            var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);

            if (item == null) return base.OnDisconnected(stopCalled);

            // GlobalContext.Clients.All.onUserDisconnected(item.ConnectionId, item.ShopId);   //调用客户端用户离线通知
            ConnectedUsers.Remove(item);
            return base.OnDisconnected(stopCalled);
        }

        #region Implement interface 'INotifiicationHubServer'

        /// <summary>
        /// 登录连线
        /// </summary>
        /// <param name="shopId"></param>
        /// <param name="accountId"></param>
        /// <param name="connectionId"></param>
        public void Join(int shopId, int accountId, string connectionId)
        {
            if (ConnectedUsers.Count(x => x.ConnectionId == connectionId) != 0) return;

            if (ConnectedUsers.Count(x => x.ShopId == shopId && x.AccountId == accountId) > 0)
            {
                ConnectedUsers.RemoveAll(x => x.ShopId == shopId && x.AccountId == accountId);
            }

            var accountRoleInfo = McAccountRoleBLL.Instance.GetModelByAccountId(accountId);

            ConnectedUsers.Add(new McConnectedClientInfo
            {
                ConnectionId = connectionId,
                ShopId = shopId,
                AccountId = accountId,
                ConnectedTime = DateTime.Now,
                RoleId = accountRoleInfo.RoleId
            });
        }

        #endregion

        #region Implement interface 'INotificationHubClient'

        public IHubContext GlobalContext { get; private set; }

        /// <summary>
        /// 推送消息
        /// </summary>
        public void NewMessage(McMessageAlertDto model)
        {
            var shopInfo = ShopsBLL.Instance.GetModel(model.ShopId);
            if (shopInfo == null)
            {
                return;
            }

            var toUsers = new List<McConnectedClientInfo>();
            if (!string.IsNullOrWhiteSpace(model.McAccountId))
            {
                
                var arrAccountId = model.McAccountId.Split(',');
                foreach (var s in arrAccountId)
                {
                    int nMcAccountId;
                    if (!int.TryParse(s, out nMcAccountId)) continue;
                    var userInfo =
                        ConnectedUsers.FirstOrDefault(x => x.ShopId == model.ShopId && x.AccountId == nMcAccountId);
                    if (userInfo != null)
                    {
                        toUsers.Add(userInfo);
                    }
                }
            }
            else
            {
                toUsers = ConnectedUsers.Where(x => x.ShopId == model.ShopId).ToList();
                if (!shopInfo.IsOpenOrderGrab)
                {
                    toUsers = ConnectedUsers.Where(x => x.ShopId == model.ShopId && x.RoleId == 1).ToList();
                }
            }

            if (!toUsers.Any()) return;
            foreach (var user in toUsers)
            {
                // send to 
                GlobalContext.Clients.Client(user.ConnectionId).NewMessage(model);
            }
        }

        #endregion
    }
}
